<template>
  <!-- 定义一个容器，用于放置Three.js渲染的画布 -->
  <div ref="canvasContainer" class="canvas-container"></div>
</template>

<script>
import * as THREE from 'three'; // 导入Three.js库
import meteoriteTexture from '@/assets/images/meteorite.png';
export default {
  name: 'SpaceParticles', // 组件名称
  data() {
    return {
      isMouseDown: false, // 跟踪鼠标点击状态
      currentSpeed: 0.5, // 当前速度
      initialSpeed: 0.5, // 初始速度
      acceleration: 2.0, // 加速增量
      deceleration: 0.1, // 减速增量
    };
  },
  mounted() {
    this.init(); // 组件挂载后调用初始化方法
  },
  methods: {
    init() {
      // 获取画布容器的引用
      const container = this.$refs.canvasContainer;
      // 获取容器的宽度和高度
      const width = container.clientWidth;
      const height = container.clientHeight;

      // 创建场景
      const scene = new THREE.Scene();

      // 创建透视相机
      const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
      camera.position.z = 5; // 设置相机的位置

      // 创建WebGL渲染器
      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(width, height); // 设置渲染器的大小
      container.appendChild(renderer.domElement); // 将渲染器的画布添加到容器中

      // 创建粒子系统
      const particlesGeometry = new THREE.BufferGeometry(); // 创建一个缓冲几何体
      const particleCount = 2000; // 粒子数量
      const positions = new Float32Array(particleCount * 3); // 创建一个数组来存储粒子的位置

      // 随机生成粒子的位置
      for (let i = 0; i < particleCount; i++) {
        positions[i * 3] = (Math.random() - 0.5) * 1000; // x坐标
        positions[i * 3 + 1] = (Math.random() - 0.5) * 1000; // y坐标
        positions[i * 3 + 2] = (Math.random() - 0.5) * 1000; // z坐标
      }

      // 将位置数据添加到几何体中
      particlesGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));

      // 创建粒子材质
      const particleMaterial = new THREE.PointsMaterial({
        color: 0xffffff, // 粒子颜色
        size: 1.5, // 粒子大小
        map: new THREE.TextureLoader().load(meteoriteTexture), // 你可以使用一个粒子纹理图片
        transparent: true, // 透明度
      });

      // 创建粒子系统
      const particleSystem = new THREE.Points(particlesGeometry, particleMaterial);
      scene.add(particleSystem); // 将粒子系统添加到场景中

      // 动画函数
      const animate = () => {
        requestAnimationFrame(animate); // 请求动画帧

        // 移动粒子
        const positions = particleSystem.geometry.attributes.position.array;

        // 根据鼠标状态调整速度
        if (this.isMouseDown) {
          this.currentSpeed += this.acceleration; // 加速
        } else {
          this.currentSpeed -= this.deceleration; // 减速
          if (this.currentSpeed < this.initialSpeed) {
            this.currentSpeed = this.initialSpeed; // 确保速度不低于初始速度
          }
        }

        for (let i = 0; i < particleCount; i++) {
          positions[i * 3 + 2] += this.currentSpeed; // 移动粒子
          if (positions[i * 3 + 2] > 800) {
            positions[i * 3] = (Math.random() - 0.5) * 800; // 重置x坐标
            positions[i * 3 + 1] = (Math.random() - 0.5) * 800; // 重置y坐标
            positions[i * 3 + 2] = -(Math.random() - 0.5) * 2000; // 重置z坐标
          }
        }
        particleSystem.geometry.attributes.position.needsUpdate = true; // 更新粒子位置

        renderer.render(scene, camera); // 渲染场景
      };

      animate(); // 开始动画

      // 调整窗口大小时更新渲染器大小
      window.addEventListener('resize', () => {
        camera.aspect = container.clientWidth / container.clientHeight; // 更新相机的纵横比
        camera.updateProjectionMatrix(); // 更新相机的投影矩阵
        renderer.setSize(container.clientWidth, container.clientHeight); // 更新渲染器的大小
      });

      // 鼠标移动事件
      let mouseX = 0, mouseY = 0; // 定义鼠标位置变量
      const onMouseMove = (event) => {
        mouseX = (event.clientX / window.innerWidth) * 2 - 1; // 计算鼠标在X轴上的位置
        mouseY = -(event.clientY / window.innerHeight) * 2 + 1; // 计算鼠标在Y轴上的位置

        camera.lookAt(mouseX * 10, mouseY * 10, 0); // 更新相机的方向
      };

      container.addEventListener('mousemove', onMouseMove); // 监听鼠标移动事件

      // 鼠标按下和释放事件
      container.addEventListener('mousedown', () => {
        this.isMouseDown = true;
      });
      container.addEventListener('mouseup', () => {
        this.isMouseDown = false;
      });
    },
  },
};
</script>

<style scoped>
.canvas-container {
  width: 100vw; /* 设置容器的宽度 */
  height: 100vh; /* 设置容器的高度 */
  overflow: hidden; /* 隐藏溢出内容 */
  background: #000; /* 设置背景颜色 */
}
</style>
